package cn.jetpiece.cloud.core.exception.aop;

import cn.jetpiece.cloud.core.exception.enums.GatewayExceptionEnum;
import cn.jetpiece.cloud.core.exception.GatewayException;
import cn.jetpiece.cloud.core.util.IpInfoUtils;
import cn.jetpiece.cloud.model.response.Result;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.WebExceptionHandler;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;

/**
 * 全局错误拦截器
 *
 * @author XuJZ
 */
@Slf4j
@Order(-200)
public class GatewayExceptionHandler implements WebExceptionHandler {

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable throwable) {
        //定义返回结果
        Result<String> responseData;
        //设置response的header
        ServerHttpResponse response = exchange.getResponse();
        ServerHttpRequest request = exchange.getRequest();
        String ip = IpInfoUtils.getIpAddr(request);
        if (throwable instanceof GatewayException) {
            GatewayException gatewayException = (GatewayException) throwable;
            Integer code = gatewayException.getCode();
            String errorMessage = gatewayException.getErrorMessage();
            responseData = Result.error(code, errorMessage);
            response.setStatusCode(HttpStatus.valueOf(code));
            log.error(ip + " 请求异常：" + responseData);
        } else if (throwable instanceof ResponseStatusException) {
            ResponseStatusException responseStatusException = (ResponseStatusException) throwable;
            HttpStatus httpStatus = responseStatusException.getStatus();
            responseData = Result.error(httpStatus.value(), request.getURI().getPath());
            response.setStatusCode(httpStatus);
            log.error(ip + " ResponseStatus异常：" + responseData);
        } else {
            responseData = Result.error(GatewayExceptionEnum.GATEWAY_ERROR.getMessage());
            response.setStatusCode(HttpStatus.valueOf(GatewayExceptionEnum.GATEWAY_ERROR.getCode()));
            log.error(ip + " 运行时异常：", throwable);
        }
        //设置headers
        HttpHeaders httpHeaders = response.getHeaders();
        httpHeaders.add("Content-Type", "application/json");
        httpHeaders.add("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
        //渲染响应信息
        String resultString = JSON.toJSONString(responseData);
        byte[] bytes = (resultString).getBytes(StandardCharsets.UTF_8);
        DataBuffer wrap = exchange.getResponse().bufferFactory().wrap(bytes);
        return exchange.getResponse().writeWith(Flux.just(wrap));
    }
}
